DockerfileをGitで管理してElastic Beanstalkでデプロイする
森永です。
ElasticBeasntalkとDockerを組み合わせると色々と夢が広がります。
Dockerでアプリケーションの実行環境を構築し、EBでAWS環境を構築して実行環境とアプリケーションをまるっとデプロイします。 これが出来るとまったく同じ環境をいくつでも作成できるようになります!
Dockerのコンテナを作成する方法はいくつかあるのですが、今回はコンテナの設計書となるDockerfileを使い作成します。 Dockerfile自体はただのテキストファイルなのでgitで管理すると捗りますし、EB CLIは公式にgitとの連携をサポートしていますので、非常に簡単に使用することが可能です。
前準備
Macで作業していきます。(OS X Yosemite Ver.10.10.3)
必要な物をインストールしておきましょう。
Macであればデフォルトでgitがインストールされているので特に問題はないかと思います。
必要に応じてアップデートして下さい。
AWS CLIとEB CLIに関してはこちらの記事を参考に、クレデンシャルの設定まで完了させておいて下さい。
プロファイルを分けておくと複数のアカウントを使いまわせるので非常に便利です。
使用できることを確認しておきます。
$ git --version git version 2.4.3 $ aws --version aws-cli/1.7.34 Python/2.7.6 Darwin/14.3.0 $ eb --version EB CLI 3.4.5 (Python 2.7.6)
バージョン情報が出ればOKです。
Gitローカルリポジトリ作成
まずは、gitのローカルリポジトリを作成します。
ここが、EBでデプロイするプロジェクトともなります。
お好きなところにディレクトリを作成して、その中でgitリポジトリの初期化を行います。
$ mkdir eb-docker $ cd eb-docker $ git init Initialized empty Git repository in /Users/morinagataishi/git/eb-docker/.git/ $ ls -al total 0 drwxr-xr-x 3 morinagataishi staff 102 6 15 16:42 . drwxr-xr-x 8 morinagataishi staff 272 6 15 16:40 .. drwxr-xr-x 9 morinagataishi staff 306 6 15 16:42 .git
.gitというディレクトリができていたらローカルリポジトリ作成成功です。
EBプロジェクトの作成
次にこのディレクトリをEBのプロジェクト(EBでデプロイするディレクトリ)として設定します。 といっても、eb initコマンドを実行して、対話的に進めていくだけです。
$ eb init Enter Application Name (default is "eb-docker"): # アプリケーション名を入力します。既存のアプリがある場合は選択肢が出ます。 Application eb-docker has been created. Select a platform. 1) PHP 2) Node.js 3) IIS 4) Tomcat 5) Python 6) Ruby 7) Docker 8) Multi-container Docker 9) GlassFish 10) Go (default is 1): 7 # 今回はDockerなので7を選択しますが、別のプラットフォームでもgit管理できます。 Do you want to set up SSH for your instances? (y/n): y # SSHログインする場合は"y"を選択します。 Select a keypair. 1) cm-morinaga 2) [ Create new KeyPair ] (default is 2): 1 # SSHログインする際のキーペアを選択します。 $ ll total 8 drwxr-xr-x 5 morinagataishi staff 170 6 15 17:03 . drwxr-xr-x 8 morinagataishi staff 272 6 15 16:40 .. drwxr-xr-x 3 morinagataishi staff 102 6 15 17:00 .elasticbeanstalk drwxr-xr-x 9 morinagataishi staff 306 6 15 16:42 .git -rw-r--r-- 1 morinagataishi staff 108 6 15 17:03 .gitignore
.elasticbeanstalkと.gitignoreが作成されています。
.gitignoreを覗いてみると
# Elastic Beanstalk Files .elasticbeanstalk/* !.elasticbeanstalk/*.cfg.yml !.elasticbeanstalk/*.global.yml
となっており、.elasticbeanstalkディレクトリはgit管理から除外されています。
ただし、.cfg.ymlと.global.ymlの拡張子のファイルだけはgitで管理されます。
EBの設定でバージョン管理したいものについてはこの拡張子を設定するようにしましょう。
Dockerfileの作成
今回はテストで、Apacheをインストールしてページを閲覧できるようにしてみます。
$ vi Dockerfile FROM ubuntu:12.04 MAINTAINER morinaga # Apacheインストール RUN apt-get update RUN apt-get install -y apache2 # 環境変数設定 ENV APACHE_RUN_USER www-data ENV APACHE_RUN_GROUP www-data ENV APACHE_LOG_DIR /var/log/apache2 ENV APACHE_LOCK_DIR /var/lock/apache2 ENV APACHE_PID_FILE /var/run/apache2.pid # アプリ(今回はHTMLファイル)配置 ADD . /var/www # コンテナポート開放 EXPOSE 80 # apacheの起動 CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]
これでちゃんとコンテナを作成できるのかをローカルでビルドしておくことをオススメします。
こちらを参考に、boot2dockerをインストールしてローカルでビルドが通ることを確かめましょう。
$ boot2docker up Waiting for VM and Docker daemon to start... ............oooo Started. (省略) $ docker build -t eb-docker . Sending build context to Docker daemon 34.82 kB Sending build context to Docker daemon Step 0 : FROM ubuntu:12.04 12.04: Pulling from ubuntu (省略) Successfully built e9c3b321a829
Successfully built ******が出ればDockerfileとして正しくビルド出来ます。
boot2docker上のDockerがバージョン1.6以上であれば、eb local runも使用できます。
$ eb local run 12.04: Pulling from ubuntu (省略) Successfully built c1a929ac5512
boot2docker上で動くのは変わりません。
環境作成
Dockerfileの準備が出来ましたので、早速EBで環境を作っていきましょう。
ただ、このまま環境構築してもDockerfileしかデプロイされないので一緒にデプロイするアプリを作成します。
といってもただのHTMLです。テストなのでご容赦下さい。
$ echo 'test' > index.html
では、気を取り直してEBで環境を作っていきます。
EBをGitと連携すると、GitでcommitされたファイルだけがEBでデプロイされます。
なので、先にGitでCommitをしてからEBの操作を行います。
まずはデプロイ対象のファイルをコミットします。
$ git add Dockerfile index.html $ git commit
続いて、EBで新規環境を構築します。dev-envという名前で作成します。
$ eb create dev-env Creating application version archive "ad0f". Uploading eb-docker/ad0f.zip to S3. This may take a while. Upload Complete. (省略) INFO: Successfully launched environment: dev-env
INFO: Successfully launched environment: 環境名で環境構築成功です!
以下のコマンドで、作成した環境にアクセスが出来ます。
$ eb open
デプロイ
次に、アプリケーションの更新を行ってからのデプロイを行ってみます。
先ほどとの違いはeb createではなくeb deployを使用することだけです。
$ echo 'test-dev' > index.html $ git add index.html $ git commit $ eb deploy Creating application version archive "35de". Uploading eb-docker/35de.zip to S3. This may take a while. Upload Complete. (省略) INFO: Environment update completed successfully.
完了したらeb openしてみましょう。デプロイされたことがわかると思います。
環境の切り替え
このGit+EBの連携の利点はアプリケーションやDockerfileのバージョン管理出来る他に、ブランチを作成して環境を切り替えられる事にあります。
先ほどまで、dev-envをMasterブランチに作成していました。
ここでprdブランチを作成し、prd-envを作成してみましょう。
prdブランチを作成し、チェックアウトします。
$ git branch prd $ git checkout prd Switched to branch 'prd' $ git branch master * prd
アプリケーションを本番仕様にして、Gitでコミットします。
$ echo 'test-prd' > index.html $ git add index.html $ git commit
この状態でprd-env環境を構築します。
$ eb create prd-env Creating application version archive "99c7". Uploading eb-docker/99c7.zip to S3. This may take a while. Upload Complete. (省略) INFO: Successfully launched environment: prd-env
eb openしてみるとprd用のアプリになっていることが分かります!
GitとEBの連携は環境作成時以外にもeb useを使用することで可能です。 以下のコマンドで、masterブランチにprd-env環境を結びつけることが出来ます。 既存のEB環境をGitで管理したい場合にはこちらを使用しましょう。
$ git checkout master $ eb use prd-env
さいごに
GitとEBの連携をするとバージョン管理、環境の切り替えが非常に用意になります。
今回はアプリケーションだけデプロイという形でしたが、Deckerfileを変更することで開発、本番で違った環境を作成可能です。
ただし、Dockerfileでの環境構築には問題があります。
一つは構築が遅いことです。
構築の遅さは、コマンドを一個一個実行して、ダウンロードして、というのをビルド時に行っているのが原因です。
もう一つは、冪等性を担保できないことです。
パッケージインストールのタイミングによってyumやaptはバージョンが変わります。
それ以外にも、Dockerfileの記述が増えれば冪等性を保つのはどんどん難しくなってきます。
これを回避する方法として、Dockerのイメージをビルドした状態で保管しておき、イメージをデプロイするということが考えられます。
既にビルドされているので、Dockerfileより早く、冪等性も担保できます。
ただ、イメージを保管するためのレジストリを用意する必要がありますので、状況に応じて使い分けましょう。
(公開のRegistryとしてDocker HubDocker Hubがあります。ただし無償版ではPublicのイメージになります。GitHubと同じ感じですね。)